﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WpfAppWcfRestConsumer
{
	internal class Win32
	{
		private Win32()
		{
		}

		public const int WM_DEVICECHANGE = 0x0219;
		// System detects a new device
		public const int DBT_DEVICEARRIVAL = 0x8000;
		// Device removal request
		public const int DBT_DEVICEQUERYREMOVE = 0x8001;
		// Device removal failed
		public const int DBT_DEVICEQUERYREMOVEFAILED = 0x8002;
		// Device removal is pending
		public const int DBT_DEVICEREMOVEPENDING = 0x8003;
		// The device has been succesfully removed from the system
		public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
		// Logical Volume (A disk has been inserted, such a usb key or external HDD)
		public const int DBT_DEVTYP_VOLUME = 0x00000002;

		//Power changed status
		public const int WM_POWERBROADCAST = 0x218;
		//wParam
		public const int PBT_APMPOWERSTATUSCHANGE = 0xA;
		public const int PBT_APMSUSPEND = 0x4;//4
		public const int PBT_APMRESUMESUSPEND = 0x7;// int 7
		public const int PBT_APMBATTERYLOW = 0x9;
		public const int PBT_APMRESUMEAUTOMATIC = 0x12;//18  
		public const int PBT_POWERSETTINGCHANGE = 0x8013;//int 32787

		//User logoff
		public const int WM_QUERYENDSESSION = 0x0011;
		public const int WM_ENDSESSION = 0x0016;

		[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
		public struct SYSTEM_POWER_STATUS
		{
			public byte ACLineStatus;
			public byte BatteryFlag;
			public byte BatteryLifePercent;
			public byte Reserved1;
			public int BatteryLifeTime;
			public int BatteryFullLifeTime;
		} ;

		[System.Runtime.InteropServices.DllImport("kernel32.dll")]
		internal static extern bool GetSystemPowerStatus(out SYSTEM_POWER_STATUS lpSystemPowerStatus);

		public enum ACLineStatus : byte
		{
			Offline = 0, Online = 1, Unknown = 255
		}

		public enum BatteryFlag : byte
		{
			High = 1,
			Low = 2,
			Critical = 4,
			Charging = 8,
			NoSystemBattery = 128,
			Unknown = 255
		}

		public static bool GetSystemPowerStatusApi()
		{
			SYSTEM_POWER_STATUS ps;
			if (GetSystemPowerStatus(out ps))
			{
				return true;
			}
			return false;
		}

		public static Boolean IsACPowerPluggedIn()
		{
			SYSTEM_POWER_STATUS SPS = new SYSTEM_POWER_STATUS();
			GetSystemPowerStatus(out SPS);

			if (SPS.ACLineStatus == (byte)ACLineStatus.Online)
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		/// <summary>
		/// Returns an integer representing the percent of battery charge remaining.
		/// </summary>
		public static Int32 BatteryCharge()
		{
			SYSTEM_POWER_STATUS SPS = new SYSTEM_POWER_STATUS();
			GetSystemPowerStatus(out SPS);

			return (Int32)SPS.BatteryLifePercent;
		}

		/// <summary>
		/// Returns an integer representing the percent of battery charge remaining.
		/// </summary>
		public static BatteryFlag GetBatteryFlag()
		{
			SYSTEM_POWER_STATUS SPS = new SYSTEM_POWER_STATUS();
			GetSystemPowerStatus(out SPS);

			return Parse(SPS.BatteryFlag);
		}

		private static BatteryFlag Parse(byte st)
		{
			switch (st)
			{
				case (byte)1:
					{
						return BatteryFlag.High;
					}

				case (byte)2:
					{
						return BatteryFlag.Low;
					}

				case (byte)4:
					{
						return BatteryFlag.Critical;
					}

				case (byte)8:
					{
						return BatteryFlag.Charging;
					}

				case (byte)128:
					{
						return BatteryFlag.NoSystemBattery;
					}

				default:
					break;
			}

			return BatteryFlag.Unknown;
		}

		//Method to detect the unit name (”D:”, “F:”, etc)
		public static char UnitName(int unitmask)
		{
			char[] units ={ 'A', 'B', 'C', 'D', 'E', 'F', 'G',
							'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
							'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
			int i = 0;
			//Convert the mask in an array, and search
			//the index for the first occurrenc (the unit's name)
			System.Collections.BitArray ba = new System.Collections.BitArray(System.BitConverter.GetBytes(unitmask));
			foreach (bool var in ba)
			{
				if (var == true)
					break;
				i++;
			}
			return units[i];
		}
	}
}
